package ge.lowlevel;

import ge.exceptions.FunctionNonSuported;

/**
 * 
 * @author Abel
 *	Utiliza el patron delegate y singleton
 */
public abstract class DrawEngine
{
	protected static DrawEngine delegated;
	public DrawEngine()
	{
		
	}
	/**
	 * 	Sets the concrete engine
	 * @param engine
	 */
	static public  void set(DrawEngine engine)
	{
		delegated = engine;
	}
	/**
	 * 	
	 * @return gets the concrete DrawEngine
	 */
	static public DrawEngine get()
	{
		return delegated;
	}
	
	/**
	 * 	Clears the screen. It will be used in the engine for clear the screen before
	 * 	each draw call.
	 */
	abstract public  void  clear();
     
	/**
	 * 	Draws a frame 
	 * @param url	Url of sprite
	 * @param canvasX	Position X in the canvas
	 * @param canvasY	Position Y in the canvas
	 * @param canvasWith	Width to draw in Canvas
	 * @param canvasHeight	Height to draw in canvas
	 * @param spriteX	Position X where start drawing for frame
	 * @param spriteY	Position Y where start drawing for frame
	 * @param frameWidth	Width to draw in sprite
	 * @param frameHeight	Height to draw in sprite
     * @throws FunctionNonSuported if the engine doesn't support it
     */
	public void drawFrame(String url,double canvasX, double canvasY, double canvasWith, double canvasHeight, double spriteX, double spriteY, double frameWidth, double frameHeight) throws FunctionNonSuported
	{
		throw new FunctionNonSuported("Draw Engine","drawFrame");
	}
	/**
	 * 	Draws a whole image 
	 * @param url	Url of sprite
	 * @param canvasX	Position X in the canvas
	 * @param canvasY	Position Y in the canvas
     * @throws FunctionNonSuported if the engine doesn't support it
     */
	public void drawImage(String url, double canvasX, double canvasY) throws FunctionNonSuported
	{
		throw new FunctionNonSuported("Draw Engine","drawImage");
	}
	/**
	 * 	Draws a Rectangle
	 * @param x1	Up-Left corner X coordinate
	 * @param y1	Up-Left corner Y coordinate
	 * @param w	 	Width of the square
	 * @param h		Height of the rectangle
	 * @throws FunctionNonSuported if the engine doesn't support it
	 */
	public void drawRectangle(double x1, double y1, double w, double h) throws FunctionNonSuported
	{
		throw new FunctionNonSuported("Draw Engine","drawSquare");
	}
	/**
	 * 	Draws text
	 * @param text	Text to be drawed
	 * @param x	X coordinate
	 * @param y	Y coordinate
	 * @param font text's font
	 * @throws FunctionNonSuported if the engine doesn't support it
	 */
	public void drawText(String text, double x, double y, String font) throws FunctionNonSuported
	{
		throw new FunctionNonSuported("Draw Engine","drawText");
	}
	/**
	 * 	Sets a color to be used in the draw context. The color is specified in (R,G,B) parameters
	 * @param R	Red value
	 * @param G	Green value
	 * @param B	Blue value
	 * @param A	Alpha of the color
	 * @throws FunctionNonSuported if the engine doesn't support it
	 */
	public void setColor(int R, int G, int B, int A) throws FunctionNonSuported
	{
		throw new FunctionNonSuported("Draw Engine","setColor");
	}
	
	/**
	 * 	Sets a color to be used in the draw context. The color is specified in (R,G,B) parameters
	 * @param R	Red value
	 * @param G	Green value
	 * @param B	Blue value
	 * @throws FunctionNonSuported if the engine doesn't support it
	 */
	public void setColor(int R, int G, int B) throws FunctionNonSuported
	{
		setColor(R, G, B,255);
	}
	/**
	 * @return The width of the canvas of the ACTUAL LAYER
	 * If you have some layers with differents sizes make sure you are asking 
	 * to the correct layer. Or use getWidth(int layer)
	 * @throws FunctionNonSuported if the engine doesn't support it
	 */
	public double getWidth() throws FunctionNonSuported
	{
		throw new FunctionNonSuported("Draw Engine","getWidth");
	}
	
	/**
	 * 	When you change the layer, all the next things to draw will be drawn in that layer
	 * @param layer The number of layers, you may have to make sure if you have that layer
	 * @throws FunctionNonSuported if the engine doesn't support it
	 */
	public void setLayer(int layer) throws FunctionNonSuported
	{
		throw new FunctionNonSuported("Draw Engine","setLayer");
	}
	/**
	 * 
	 * @return The number of layers
	 * @throws FunctionNonSuported if the engine doesn't support it
	 */
	public int getNumLayers() throws FunctionNonSuported
	{
		throw new FunctionNonSuported("Draw Engine","getNumLayers");
	}
	/**
	 * @return The height of the canvas
	 * If you have some layers with differents sizes make sure you are asking 
	 * to the correct layer. Or use getWidth(int layer)
	 * @throws FunctionNonSuported if the engine doesn't support it
	 */
	public double getHeight() throws FunctionNonSuported
	{
		throw new FunctionNonSuported("Draw Engine","getHeight");
	}
	/**
	 * 	Move the context to that position, in order to start to draw there.
	 * @param x Point x
	 * @param y Point y 
	 * @throws FunctionNonSuported if the engine doesn't support it
	 */
	public void moveTo(double x, double y) throws FunctionNonSuported
	{
		throw new FunctionNonSuported("Draw Engine","moveTo");
	}
	/**
	 * 	Draw a line between the last context position to that new position
	 * @param x Point x
	 * @param y Point y 
	 * @throws FunctionNonSuported if the engine doesn't support it
	 */
	public void lineTo(double x, double y) throws FunctionNonSuported
	{
		throw new FunctionNonSuported("Draw Engine","lineTo");
	}
	/**
	 * 	To draw some patterns, like a point a point shape, you have
	 * to start a path and end it.
	 * @param start if true, it will be like BeginPath, if false, like EndPath
	 * @throws FunctionNonSuported if the engine doesn't support it
	 */
	public void setPath(boolean start) throws FunctionNonSuported
	{
		throw new FunctionNonSuported("Draw Engine","setPath");
	}
	/**
	 * Fill a area, it can be one area set by a path
	 * @throws FunctionNonSuported if the engine doesn't support it
	 */
	public void fill() throws FunctionNonSuported
	{
		throw new FunctionNonSuported("Draw Engine","fill");
	}
	/**
	 * Draw the borde of a area, it can be one area set by a path
	 * @throws FunctionNonSuported if the engine doesn't support it
	 */
	public void stroke() throws FunctionNonSuported
	{
		throw new FunctionNonSuported("Draw Engine","fill");
	}
	/**
	 * 	
	 * @param x Position x 
	 * @param y Position y
	 * @param radio Radio of the circle
	 * @throws FunctionNonSuported FunctionNonSuported if the engine doesn't support it
	 */
	public void drawCircle(double x, double y, double radio) throws FunctionNonSuported
	{
		throw new FunctionNonSuported("Draw Engine","drawCircle");
	}
	/**
	 * 	Tells to the DrawEngine that has to load and prepare that image to be painted
	 * @param imageUrl Url direction of the image
	 * @throws FunctionNonSuported if the engine doesn't support it
	 */
	public void loadImage(String imageUrl) throws FunctionNonSuported
	{
		throw new FunctionNonSuported("Draw Engine","loadImage");
	}
	
	/**
	 * 	Consult if the image asked to be loaded with loadImage is just loaded. If you ask
	 * to draw directly without ask to load first, the engine won't be monitoring the load process
	 * and that function always with return false
	 * @param imageUrl Url direction of the image
	 * @return True if the image has been loaded. 
	 * @throws FunctionNonSuported
	 */
	public boolean isImageLoaded(String imageUrl) throws FunctionNonSuported
	{
		throw new FunctionNonSuported("Draw Engine","isImageLoaded");
	}
	 
}
